package com.kedacom.ctsp.authz.access;

import com.google.common.collect.Sets;
import com.kedacom.ctsp.authz.Authorize;
import com.kedacom.ctsp.authz.entity.AuthResource;
import com.kedacom.ctsp.authz.entity.Authentication;
import com.kedacom.ctsp.orm.param.Param;
import com.kedacom.ctsp.orm.param.UpdateParam;
import com.kedacom.ctsp.web.entity.CreatorRecordableBean;
import com.kedacom.ctsp.web.entity.UpdaterRecordableBean;
import com.kedacom.ctsp.web.vo.VO;
import org.apache.commons.collections.CollectionUtils;

import java.util.List;
import java.util.Set;

/**
 * 基础数据权限过滤
 *
 * @author xuwei
 * @create 2017-11-29 15:01
 **/
public class FieldDataAccessHandler extends DataAccessHandlerAdaptor {

    @Override
    protected boolean handleVo(Authentication auth, List<AuthResource> authResources, Authorize anno, VO target) {
        updateEntity(auth, target);
        return true;
    }

    @Override
    protected boolean handleQuery(Authentication authUser, List<AuthResource> authResources, Authorize anno, Param target) {
        updateParam(authResources, target);
        return true;
    }

    @Override
    protected boolean handleUpdate(Authentication authUser, List<AuthResource> authResources, Authorize anno, UpdateParam target) {
        updateEntity(authUser, target.getData());
        updateParam(authResources, target);
        return true;
    }

    /**
     * 处理过滤字段
     * 如果什么都没有配置-> 有全部字段权限
     * 如果配置了-> 只有有配置的字段可见
     *
     * @param authResources
     * @param target
     */
    private void updateParam(List<AuthResource> authResources, Param target) {
        Set<String> excludeFields = Sets.newHashSet();
        Set<String> includeFields = Sets.newHashSet();
        for (AuthResource authResource : authResources) {
            // 处理过滤字段
            if (CollectionUtils.isNotEmpty(authResource.getExcludeFields())) {
                excludeFields.addAll(authResource.getExcludeFields());
            }
            if (CollectionUtils.isNotEmpty(authResource.getIncludeFields())) {
                includeFields.addAll(authResource.getIncludeFields());
            }
        }
        if (CollectionUtils.isNotEmpty(target.getIncludes())) {
            includeFields = Sets.newHashSet(CollectionUtils.intersection(includeFields, target.getIncludes()));
        }
        if (CollectionUtils.isNotEmpty(target.getExcludes())) {
            excludeFields.addAll(target.getExcludes());
        }
        target.setExcludes(excludeFields);
        target.setIncludes(includeFields);
    }


    private void updateEntity(Authentication authUser, Object target) {
        if (target instanceof CreatorRecordableBean) {
            ((CreatorRecordableBean) target).setCreateTimeNow();
            ((CreatorRecordableBean) target).setCreatorId(authUser.getUser().getId());
        }
        if (target instanceof UpdaterRecordableBean) {
            ((UpdaterRecordableBean) target).setUpdateTimeNow();
            ((UpdaterRecordableBean) target).setUpdaterId(authUser.getUser().getId());
        }
    }
}
